﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class StudentExercise
{
    public enum Specialties {
                                ComputerSciences=1,
                                Informatics,
                                Mathematics,
                            };
    public enum Faculties {
                             FMI=1,
                             BiologicalFaculty,
                             HistoryFaculty,
                             LawFaculty,
                          };
    public enum Universities
                             {
                                SofiaUniversity=1,
                                VIAS,
                                UNSS,
                             };

    public class Student : ICloneable, IComparable<Student>
    {
        private string names;
        private string ssn;
        private string pemanentAddress;
        private string phone;
        private string email;
        private int course;
        private Faculties faculty;
        private Universities university;
        private Specialties specialty;

        public Student(string names, string ssn, string pemanentAddress, string phone, string email, int course, Faculties faculty, Universities university, Specialties specialty)
        {
            this.Names = names;
            this.SSN = ssn;
            this.PemanentAddress = pemanentAddress;
            this.Phone = phone;
            this.Email = email;
            this.Course = course;
            this.Faculty = faculty;
            this.University = university;
            this.Specialty = specialty;
        }
        //public Student()
        //    : this("none", "none", "none", "none", "none", 1, Faculties.None, Universities.None, Specialties.None)
        //{ }

        public string Names
        {
            get
            {
                return names;
            }
            set
            {
                if (value != null && value != "")
                {
                    names = value;
                }
                else
                {
                    throw new ArgumentException("Invalid Name");
                }
            }
        }
        public string SSN
        {
            get
            {
                return ssn;
            }
            set
            {
                if (value != null && value != "")
                {
                    ssn = value;
                }
                else
                {
                    throw new ArgumentException("Invalid SSN");
                }
            }
        }
        public string PemanentAddress
        {
            get
            {
                return pemanentAddress;
            }
            set
            {
                if (value != null && value != "")
                {
                    pemanentAddress = value;
                }
                else
                {
                    throw new ArgumentException("Invalid PermanentAddress");
                }
            }
        }
        public string Phone
        {
            get
            {
                return phone;
            }
            set
            {
                if (value != null && value != "")
                {
                    phone = value;
                }
                else
                {
                    throw new ArgumentException("Invalid Phone");
                }

            }
        }
        public string Email
        {
            get
            {
                return email;
            }
            set
            {
                if (value != null)
                {
                    email = value;
                }
                else
                {
                    throw new ArgumentException("Invalid Email");
                }
            }
        }
        public int Course
        {
            get
            {
                return course;
            }
            set
            {
                if (value > 0 && value < 7)
                {
                    course = value;
                }
                else
                {
                    throw new ArgumentException("Invalid SSN");
                }
            }
        }
        public StudentExercise.Faculties Faculty
        {
            get
            {
                return faculty;
            }
            set
            {
                faculty = value;
            }
        }
        public StudentExercise.Universities University
        {
            get
            {
                return university;
            }
            set
            {
                university = value;
            }
        }
        public StudentExercise.Specialties Specialty
        {
            get
            {
                return specialty;
            }
            set
            {
                specialty = value;
            }
        }

        public override bool Equals(object obj)
        {
            Student st;
            if (!object.ReferenceEquals((st = obj as Student), null))
            {
                if (!st.Names.Equals(this.names))
                {
                    return false;
                }
                if (!st.SSN.Equals(this.ssn))
                {
                    return false;
                }
                if (!st.PemanentAddress.Equals(this.pemanentAddress))
                {
                    return false;
                }
                if (!st.Phone.Equals(this.phone))
                {
                    return false;
                }
                if (!st.Email.Equals(this.email))
                {
                    return false;
                }
                if (!st.Course.Equals(this.course))
                {
                    return false;
                }
                if (!st.Specialty.Equals(this.specialty))
                {
                    return false;
                }
                if (!st.University.Equals(this.university))
                {
                    return false;
                }
                if (!st.Faculty.Equals(this.faculty))
                {
                    return false;
                }
                return true;
            }
            return false;
        }
        public override string ToString()
        {
            return string.Format("Names: {0}\nSSN: {1}\nPermanent Address: {2}\nMobile Phone: {3}\nE-mail: {4}\n" + 
                                 "Course: {5}\nUniversity: {6}\nFaculty: {7}\nSpecialty: {8}",
                                 names, ssn, pemanentAddress, phone, email, course, university, faculty, specialty);
        }
        public override int GetHashCode()
        {
            return names.GetHashCode()*1<<9 ^ ssn.GetHashCode()*2<<8 ^ pemanentAddress.GetHashCode()*3<<7 
                    ^ phone.GetHashCode()*4<<6 ^ email.GetHashCode()*5<<5 ^ course.GetHashCode()*6<<4
                    ^ specialty.GetHashCode()*7<<3 ^ university.GetHashCode()*8<<2 ^ faculty.GetHashCode()*9<<1;
        }
        public static bool operator ==(Student firstStudent, Student secondStudent)
        {
            return firstStudent.Equals(secondStudent);
        }
        public static bool operator !=(Student firstStudent, Student secondStudent)
        {
            return !(firstStudent == secondStudent);
        }
        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public Student Clone()
        {
            Student res = (Student)this.MemberwiseClone();
            return res;
        }

        public int CompareTo(Student other)
        {
            int cmp;
            if ((cmp = this.names.CompareTo(other.Names)) == 0)
            {
                return this.ssn.CompareTo(other.SSN);
            }
            return cmp;
        }
    }

    static void Main()
    {
        Student st1 = new Student("a", "az", "a", "a", "a", 1, Faculties.BiologicalFaculty, Universities.SofiaUniversity, Specialties.ComputerSciences);
        Student st2 = new Student("a", "a", "a", "a", "a", 1, Faculties.BiologicalFaculty, Universities.SofiaUniversity, Specialties.ComputerSciences);
        Console.WriteLine(st1.Equals(st2));
        Student z = null;
        Console.WriteLine(st1.Equals("asas"));
        Console.WriteLine(st1.GetHashCode());
        Console.WriteLine(st2.GetHashCode());

        Student pe6o = st2.Clone();
        pe6o.SSN = "aaz";
        Console.WriteLine(st2 == pe6o);
        Console.WriteLine(st1.CompareTo(pe6o));
    }
}
